package com.quectel.util.security;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.HmacAlgorithm;
import com.quectel.util.ex.CheckErrorException;

import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;
import java.util.UUID;

/**
 * @author caolu
 * @email louis.cao@quectel.com
 */
public class RandomHeaderSignUtils {

    public static final String SECRET_KEY = "quectel@12345678987654321@@!";

    /**
     * 对指定值进行签名 然后header传入到对方接口
     *
     * @param secretKey
     * @return
     */
    public static Map<String, String> sign(String secretKey) {


        TreeMap<String, String> treeMap = new TreeMap<>();

        String millis = String.valueOf(System.currentTimeMillis());
        String nonceStr = UUID.randomUUID().toString();

        treeMap.put("millis", millis);
        treeMap.put("noncestr", nonceStr);

        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : treeMap.entrySet()) {
            sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }

        treeMap.put("sign",
                SecureUtil.hmac(HmacAlgorithm.HmacSHA256, secretKey.getBytes(StandardCharsets.UTF_8))
                        .digestHex(sb.toString()));

        return treeMap;
    }

    /**
     * 验签
     *
     * @param secretKey
     * @param params    从header接收验签数据
     * @return
     */
    public static boolean checkSign(Map<String, String> params, String secretKey) {

        String millis = params.get("millis");
        String sign = params.get("sign");
        String nonceStr = params.get("noncestr");
        if (sign == null || millis == null || nonceStr == null) {
            return false;
        }

        if (Math.abs(Long.parseLong(millis) - System.currentTimeMillis()) > 30L * 60 * 1000) {
            throw new CheckErrorException("Request time can not match server time");
        }

        TreeMap<String, String> treeMap = new TreeMap<>();
        treeMap.put("millis", millis);
        treeMap.put("noncestr", nonceStr);

        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : treeMap.entrySet()) {
            sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }

        String recSign = SecureUtil.hmac(HmacAlgorithm.HmacSHA256, secretKey.getBytes(StandardCharsets.UTF_8))
                .digestHex(sb.toString());
        if (!Objects.equals(sign, recSign)) {
            return false;
        }

        return true;
    }


}
